package com.opgea.crm.services;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.opgea.crm.common.constant.ApplicationConstant;
import com.opgea.crm.common.util.DateUtil;
import com.opgea.crm.common.vo.DatePeriodVo;
import com.opgea.crm.common.vo.OpportunityVo;
import com.opgea.crm.domain.entities.Opportunity;
import com.opgea.crm.domain.modal.QualifierModel;
import com.opgea.crm.repository.OpportunityRepo;

@Service
public class OpportunityServiceImpl implements OpportunityService {

	@Autowired
	OpportunityRepo opportunityRepo;
	
	@Transactional(propagation=Propagation.REQUIRED)
	public void create(Opportunity opportunity) {
		// TODO Auto-generated method stub
		opportunityRepo.create(opportunity);
	}
	
	@Transactional(propagation=Propagation.REQUIRED)
	public void update(Opportunity opportunity)
	{
		opportunityRepo.update(opportunity);
	}

	@Transactional(propagation=Propagation.REQUIRED)
	public void remove(long id) {
		// TODO Auto-generated method stub
		opportunityRepo.remove(id);
		
	}

	public Opportunity find(long id) {
		return opportunityRepo.find(id);
	}

	public List<Opportunity> findAll() {
		return opportunityRepo.findAll();
	}

	public List<QualifierModel> findAllOpportunitiesTitles(){

		List<Opportunity> opportunities = opportunityRepo.findAll();
		List<QualifierModel> oppNameList = new ArrayList<QualifierModel>();
		for(Opportunity opportunity : opportunities){
			oppNameList.add(new QualifierModel(opportunity.getId(), opportunity.getOpportunityTitle()));
			
		}
		return oppNameList;
	}
	
	public List<QualifierModel> findAllOpportunitiesTitlesByLeadId(Long leadId) {
		List<Opportunity> opportunities = opportunityRepo.findAllByLeadId(leadId);
		List<QualifierModel> oppNameList = new ArrayList<QualifierModel>();
		for(Opportunity opportunity : opportunities){
			oppNameList.add(new QualifierModel(opportunity.getId(), opportunity.getOpportunityTitle()));
			
		}
		return oppNameList;
	}	
	
	
	@Transactional(propagation=Propagation.SUPPORTS)
	public List<OpportunityVo> findOpportunityList(String criteria, String value)
	{
		List<OpportunityVo> list=new ArrayList<OpportunityVo>();
		List<Opportunity> opportunities=opportunityRepo.findOpportunityList(criteria,value);
		  for(Opportunity opportunity:opportunities)
		  {
			  OpportunityVo opportunityVo = new OpportunityVo();
			  opportunityVo.setId(opportunity.getId());
			  if(opportunity.getConfidenceLevel()!= null){
			  opportunityVo.setOppClosingProbability(opportunity.getConfidenceLevel().getFieldValue());
	    	  opportunityVo.setOppClosingProbabilityId(opportunity.getConfidenceLevel().getId());
			  }
			  if(opportunity.getDealSize()!= null)
			  opportunityVo.setDealSize(String.valueOf(opportunity.getDealSize()));
			  opportunityVo.setOpportunityTitle(opportunity.getOpportunityTitle());
			  if(opportunity.getSalesPerson()!= null)
			  opportunityVo.setSalesPerson(opportunity.getSalesPerson().getFirstName());
			  if(opportunity.getStage()!= null){
			  opportunityVo.setStage(opportunity.getStage().getFieldValue());
			  opportunityVo.setStageId(opportunity.getStage().getId());
			  }
			  if(opportunity.getOpportunityStatus()!= null){
			  opportunityVo.setStatus(opportunity.getOpportunityStatus().getFieldValue());
			  opportunityVo.setStatusId(opportunity.getOpportunityStatus().getId());
			  }
			  if(opportunity.getRelatedContact()!= null)
			  opportunityVo.setCompanyName(opportunity.getRelatedContact().getCompany().getName());
			  String desc = new String(opportunity.getOpportunityDescription());
			  opportunityVo.setOpportunityDiscription(desc);
			  opportunityVo.setTargetDate(DateUtil.dateToString(opportunity.getForecastClosingDate()));
			  opportunityVo.setCreateDate(DateUtil.dateToString(opportunity.getCreatedDate()));
			  opportunityVo.setActualCloseDate(DateUtil.dateToString(opportunity.getActualCloseDate()));
			  
			  list.add(opportunityVo);
		  }
	    return  list;
		
	}

	public List<OpportunityVo> findAllByLeadId(long leadId) {
		
		List<OpportunityVo> oppList=new ArrayList<OpportunityVo>();
    	for(Opportunity data: opportunityRepo.findAllByLeadId(leadId))
    	{
    		OpportunityVo opportunityVo=  new OpportunityVo(); 
    		opportunityVo.setId(data.getId());
    		opportunityVo.setOpportunityTitle(data.getOpportunityTitle());
    		if(data.getDealSize()!= null)
    		opportunityVo.setDealSize(Integer.toString(data.getDealSize()));
    		if(data.getConfidenceLevel()!= null){
    		opportunityVo.setOppClosingProbability(data.getConfidenceLevel().getFieldValue());
    		opportunityVo.setOppClosingProbabilityId(data.getConfidenceLevel().getId());
    		 }
    		if(data.getSalesPerson()!= null){
    			opportunityVo.setSalesPerson(data.getSalesPerson().getFirstName());
    			opportunityVo.setSalesPersonId(data.getSalesPerson().getId());
    		}
    		if(data.getStage()!= null){
    		opportunityVo.setStage(data.getStage().getFieldValue());
			opportunityVo.setStageId(data.getStage().getId());
    		 }
    		if(data.getOpportunityStatus()!= null){
			opportunityVo.setStatus(data.getOpportunityStatus().getFieldValue());
			opportunityVo.setStatusId(data.getOpportunityStatus().getId());
    		 }
    		if(data.getRelatedContact()!= null)
    		opportunityVo.setCompanyName(data.getRelatedContact().getCompany().getName());
    		
    		String desc = new String(data.getOpportunityDescription());
			opportunityVo.setOpportunityDiscription(desc);
			opportunityVo.setTargetDate(DateUtil.dateToString(data.getForecastClosingDate()));
		    opportunityVo.setCreateDate(DateUtil.dateToString(data.getCreatedDate()));
			opportunityVo.setActualCloseDate(DateUtil.dateToString(data.getActualCloseDate()));
    		oppList.add(opportunityVo);
    		System.out.println("Opportunity :"+opportunityVo);
    	
    	}
    	return oppList;
	}
	
	public List<QualifierModel> getOpportunitySearchCriteriaTypes(){
		List<QualifierModel> opportunitySearchTypes = new ArrayList<QualifierModel>();
		for(ApplicationConstant.OpportunitySearchCriteriaQualifier qualifier : ApplicationConstant.OpportunitySearchCriteriaQualifier.values()){
			opportunitySearchTypes.add(new QualifierModel(Long.valueOf(qualifier.ordinal()), qualifier.name()));
		}
		return opportunitySearchTypes;
	}
	
	
public DatePeriodVo findPeriod(String periodQualifier){
		
		DatePeriodVo datePeriodVo = null;
		Calendar cal = GregorianCalendar.getInstance();
		int year = cal.getTime().getYear();
		int month = cal.getTime().getMonth();
		int date = cal.getTime().getDate();
		
		System.out.println(year+" "+month+" "+date);
		NumberFormat formatter = new DecimalFormat("00"); 
		

		String currentYear = String.valueOf(year+1900);
		String currentMonth = String.valueOf(formatter.format(month+1));
		String currentDate = String.valueOf(formatter.format(date));
		
		String lastYear = String.valueOf(year+1900-1);
		String lastMonth = String.valueOf(formatter.format(month));
		int quarter = getQuarter(month);

		if(Integer.valueOf(periodQualifier) == ApplicationConstant.PeriodQualifier.Custom.ordinal()){
			datePeriodVo = new DatePeriodVo("", "");
		}
		if(Integer.valueOf(periodQualifier) == ApplicationConstant.PeriodQualifier.CurrentYear.ordinal()){
			datePeriodVo = new DatePeriodVo(currentYear+"-01-01", currentYear+"-12-31");
		}
		if(Integer.valueOf(periodQualifier) == ApplicationConstant.PeriodQualifier.LastYear.ordinal()){
			datePeriodVo = new DatePeriodVo(lastYear+"-01-01", lastYear+"-12-31");
		}
		if(Integer.valueOf(periodQualifier) == ApplicationConstant.PeriodQualifier.LastMonth.ordinal()){
			if(month == 0){
				datePeriodVo = new DatePeriodVo(lastYear+"-12-01", lastYear+"-12-31");
			}
			else{
				datePeriodVo = new DatePeriodVo(currentYear+"-"+lastMonth+"-01", currentYear+"-"+lastMonth+"-30");
			}
		}
		if(Integer.valueOf(periodQualifier) == ApplicationConstant.PeriodQualifier.CurrentQuarter.ordinal()){
			if(quarter == 1){
				datePeriodVo = new DatePeriodVo(currentYear+"-01-01", currentYear+"-03-31");
			}
			if(quarter == 2){
				datePeriodVo = new DatePeriodVo(currentYear+"-04-01", currentYear+"-06-30");
			}
			if(quarter == 3){
				datePeriodVo = new DatePeriodVo(currentYear+"-07-01", currentYear+"-09-30");
			}
			if(quarter == 4){
				datePeriodVo = new DatePeriodVo(currentYear+"-10-01", currentYear+"-12-31");
			}			
		}
		if(Integer.valueOf(periodQualifier) == ApplicationConstant.PeriodQualifier.LastQuarter.ordinal()){
			quarter = quarter -1;
			if(quarter == 1){
				datePeriodVo = new DatePeriodVo(currentYear+"-01-01", currentYear+"-03-31");
			}
			if(quarter == 2){
				datePeriodVo = new DatePeriodVo(currentYear+"-04-01", currentYear+"-06-30");
			}
			if(quarter == 3){
				datePeriodVo = new DatePeriodVo(currentYear+"-07-01", currentYear+"-09-30");
			}
			if(quarter == 4){
				datePeriodVo = new DatePeriodVo(currentYear+"-10-01", currentYear+"-12-31");
			}
		}		
		return datePeriodVo;
	}
	
	public int getQuarter(int month){
			int quarter = 0;
			if(month <= 2){
				quarter = 1;
			}
			if(month > 2 && month <= 5){
				quarter = 2;
			}
			if(month > 5 && month <= 8){
				quarter = 3;
			}
			if(month > 8 && month <= 11){
				quarter = 4;
			}
		return quarter;
	}
	
	
	public List<OpportunityVo> findReport(String periodFrom, String periodTo,String statusType, String stageType )
	{
		List<OpportunityVo> opportunities = new ArrayList<OpportunityVo>();
		List<Opportunity> opportunityList = opportunityRepo.findReport(periodFrom, periodTo, statusType, stageType);
		for(Opportunity opportunity : opportunityList)
		{
			OpportunityVo opportunityvo = new OpportunityVo();
			System.out.println("Opportunity : "+opportunityvo);
			opportunityvo.setId(opportunity.getId());
			if(opportunity.getOpportunityStatus()!= null)
			{
			opportunityvo.setStatus(opportunity.getOpportunityStatus().getFieldValue());
			opportunityvo.setStatusId(opportunity.getOpportunityStatus().getId());
			}
			if(opportunity.getStage()!= null)
			{
				opportunityvo.setStage(opportunity.getStage().getFieldValue());
				opportunityvo.setStageId(opportunity.getStage().getId());
			}
			opportunityvo.setOpportunityTitle(opportunity.getOpportunityTitle());
			if(opportunity.getRelatedContact() != null)
			    opportunityvo.setCompanyName(opportunity.getRelatedContact().getCompany().getName());
			if(opportunity.getSalesPerson() != null)
			    opportunityvo.setSalesPerson(opportunity.getSalesPerson().getFirstName());
			if(opportunity.getConfidenceLevel()!= null){
				opportunityvo.setOppClosingProbability(opportunity.getConfidenceLevel().getFieldValue());
				opportunityvo.setOppClosingProbabilityId(opportunity.getConfidenceLevel().getId());
	    		 }
			opportunities.add(opportunityvo);
		}
		return opportunities;	
	}



/*	@Override
	public List<Opportunity> findAllByCompanyId(long companyId) {
		// TODO Auto-generated method stub
		return opportunityRepo.findAllByCompanyId(companyId);
	}
	*/
	
}
